/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Driver Module                                  */
/*                                                                           */
/*    Copyright (C) 2008 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    Module: drvUART - UART Driver                                          */
/*                                                                           */
/*    IOconfig declarations:                                                 */
/*      SYSTEM_CLOCK = CPU clock used for baud rate calculations [MHz]       */
/*      UART1_BAUD_RATE = Desired baud UART1 [baud]                          */
/*      UART2_BAUD_RATE = Desired baud rate for UART2 [baud]                 */
/*****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Includes
#define USE_AND_OR
#include <uart.h>
#include <drvUART.h>
#include "drvIOConfig.h"

///////////////////////////////////////////////////////////////////////////////
// Defines
#ifdef UART_BAUD_RATE
#define UART1_BAUD_RATE UART_BAUD_RATE
#define UART2_BAUD_RATE UART_BAUD_RATE
#endif

///////////////////////////////////////////////////////////////////////////////
// Module global variables
static volatile dosBool l_uart1_character_pending = dosFalse;
static volatile dosBool l_uart2_character_pending = dosFalse;

/*****************************************************************************/
/* UART 1 Functions                                                          */
/*****************************************************************************/
#ifdef drvUART1_ENABLED 

///////////////////////////////////////////////////////////////////////////////
// Initialize UART driver
void drvUART1Init(void)
{
	// open uart
	OpenUART1(UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, // Module is ON
			      UART_TX_ENABLE | UART_INT_TX | UART_RX_ENABLE | UART_INT_RX_CHAR,		        // Enable TX & RX
			      sysPBLCK_FREQUENCY/16/UART1_BAUD_RATE-1);    // Set baudrate

	// Configure uart interrupt
	ConfigIntUART1( UART_RX_INT_EN | UART_TX_INT_EN | UART_ERR_INT_DIS | UART_INT_PR2 );
}

///////////////////////////////////////////////////////////////////////////////
// Send byte on UART
void drvUART1SendCharacter( dosChar in_byte )
{
	U1TXREG = in_byte;
}

///////////////////////////////////////////////////////////////////////////////
// Enable transmit interrupt
void drvUART1EnableTransmitInterrupt(void)
{
  if( U1STAbits.UTXBF == 0 )
		krnlUART1TransmitInterrupt();
	else
		l_uart1_character_pending = dosTrue;
}

///////////////////////////////////////////////////////////////////////////////
// Disable transmit itnerrupt
void drvUART1DisableTransmitInterrupt(void)
{
  l_uart1_character_pending = dosFalse;
}

///////////////////////////////////////////////////////////////////////////////
// UART 1 interrupt handler
void __ISR(_UART1_VECTOR, ipl2) IntUart1Handler(void)
{
	// Handle RX interrupt
	if(mU1RXGetIntFlag())
	{
		// Clear the RX interrupt Flag
	  mU1RXClearIntFlag();

		// Process received data
		krnlUART1ReceiveInterrupt(ReadUART1());
	}

	// Handle TX interrupt
	if( mU1TXGetIntFlag() )
	{
		mU1TXClearIntFlag();
		
		if( l_uart1_character_pending )
	  	krnlUART1TransmitInterrupt();
	}
}
#endif

/*****************************************************************************/
/* UART 2 Functions                                                          */
/*****************************************************************************/

#ifdef drvUART2_ENABLED 
///////////////////////////////////////////////////////////////////////////////
// Initialize UART driver
void drvUART2Init(void)
{
	// open uart
	OpenUART2(UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, // Module is ON
			      UART_TX_ENABLE | UART_INT_TX | UART_RX_ENABLE | UART_INT_RX_CHAR,		        // Enable TX & RX
			      sysPBLCK_FREQUENCY/16/UART2_BAUD_RATE-1);    // Set baudrate

	// Configure uart interrupt
	ConfigIntUART2( UART_RX_INT_EN | UART_TX_INT_EN | UART_ERR_INT_DIS | UART_INT_PR2 );
}

///////////////////////////////////////////////////////////////////////////////
// Send byte on UART
void drvUART2SendCharacter( dosChar in_byte )
{
	U2TXREG = in_byte;
}

///////////////////////////////////////////////////////////////////////////////
// Enable transmit interrupt
void drvUART2EnableTransmitInterrupt(void)
{
  if( U2STAbits.UTXBF == 0 )
		krnlUART2TransmitInterrupt();
	else
		l_uart2_character_pending = dosTrue;
}

///////////////////////////////////////////////////////////////////////////////
// Disable transmit itnerrupt
void drvUART2DisableTransmitInterrupt(void)
{
  l_uart2_character_pending = dosFalse;
}

///////////////////////////////////////////////////////////////////////////////
// UART 2 interrupt handler
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)
{
	// Handle RX interrupt
	if(mU2RXGetIntFlag())
	{
		// Clear the RX interrupt Flag
	  mU2RXClearIntFlag();

		// Process received data
		krnlUART2ReceiveInterrupt(ReadUART2());
	}

	// Handle TX interrupt
	if( mU2TXGetIntFlag() )
	{
		mU2TXClearIntFlag();
		
		if( l_uart2_character_pending )
	  	krnlUART2TransmitInterrupt();
	}
}
#endif
